/*
 * Title: 快速入门C++模板知识
 * Author: Yuanshun L
 * Created: 05-Otc-2021
 */

#include<iostream> // 标准输入输出cout,cin
#include<cmath> // 导入pow()，同#include<math.h>,C++推荐现在的方式
// cstring,cstdio,cctype同
#include<algorithm> // 导入sort()

// 将iostream和algorithm库中的函数加入默认的名称空间中
// 使用这些函数时就不必加上"std::"
using namespace std;

template <typename T> // 定义模模板，数据类型更加灵活
struct Point{
    T x,y;
    // C++允许结构体定义函数，通过p.func来调用函数
    // 构造函数，与结构体同名，可以定义多个结构体
    // 默认参数
    Point(T x=0,T y=0):x(x),y(y){
        // x(x),y(y)表示把形参x,y赋值给属性x,y,等价于下面两行代码
        // this->x = x; // this表示指向当前对象的指针,等价于(*this).x = x;
        // this->y = y;
    }
};

template <typename T>
Point<T> operator+(const Point<T> &A, const Point<T> &B){
    return Point<T>(A.x+B.x,A.y+B.y);
}

template <typename T>
bool operator<(const Point<T> &A, const Point<T> &B){
    if(pow(A.x,2)+pow(A.y,2)>pow(B.x,2)+pow(B.y,2)){
        return true;
    }
    return false;
}

template<typename T>
ostream& operator<<(ostream &out, const Point<T>& A){
    out<<"("<<A.x<<","<<A.y<<")";
    return out;
}

int main(){
    Point<double> ps[4];
    ps[0] = Point<double>(4,1);
    ps[1] = Point<double>(3,5);
    ps[2] = Point<double>(2,3.4);
    ps[3] = Point<double>(7,1);
    // sort排序的类型可以是内置数据类型，也可以是自定义类型，
    // 自定义类型要求定义了"小于"符号。
    sort(ps,ps+4);
    for(int i=0;i<4;i++){
        cout<<ps[i];
    }
    return 0;
}

